﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;

using Newtonsoft.Json.Linq;

using BOSS.Framework;
using BOSS.Framework.Search.Context;
using BOSS.Domain.Products;
using BOSS.Service.Products;
using BOSS.Service.Customers;
using BOSS.Domain.Customers;

namespace BOSS.Web.Controllers
{
    /// <summary>
    /// 产品管理控制器
    /// </summary>
    public class ProductController : AbstractController
    {
        /// <summary>
        /// 获取 / 设置 产品服务
        /// </summary>
        public IProductService ProductService { get; set; }

        /// <summary>
        /// 获取 / 设置 客户服务
        /// </summary>
        public ICustomerService CustomerService { get; set; }


        /// <summary>
        /// 创建或修改产品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Create(int? id)
        {
            Product product = null;
            if (id == null)
            {
                product = new Product();
            }
            else
            {
                product = this.ProductService.FindById(id.Value);
            }

            if (this.Request.IsPost())
            {
                TryUpdateModel(product, new[] { "Name", "Model", "Specification", "Marketable", "UseCount", "ProcurementPrice", "SellingPrice" });

                if (ModelState.IsValid)
                {
                    this.ProductService.SaveOrUpdate(product);
                    return View("Details", product);
                }
                return View(product);
            }

            if (id == null)
            {
                return View();
            }
            else
            {
                return View(product);
            }
        }

        /// <summary>
        /// 产品详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                throw new LogicalException();
            }

            Product product = this.ProductService.FindById(id.Value);
            if (product == null)
            {
                throw new LogicalException();
            }

            return View(product);
        }

        /// <summary>
        /// 产品搜索
        /// </summary>
        /// <param name="start"></param>
        /// <param name="limit"></param>
        /// <param name="sort"></param>
        /// <param name="dir"></param>
        /// <returns></returns>
        public ActionResult Search(int? start, int? limit, string sort, string dir)
        {
            if (this.Request.IsPost())
            {
                return base.ShowSearchResult("SearchResult", "Product", start, limit, sort, dir);
            }

            return View();
        }

        /// <summary>
        /// 购买产品
        /// </summary>
        /// <returns></returns>
        public ActionResult Purchase(int? customerAccountId, string purchaseItems)
        {
            if (this.Request.IsPost()
                && customerAccountId != null
                && !string.IsNullOrEmpty(purchaseItems) 
                && purchaseItems.StartsWith("[") 
                && purchaseItems.EndsWith("]"))
            {
                PurchaseRecord purchaseRecord = new PurchaseRecord();
                purchaseRecord.CustomerAccount = this.CustomerService.FindCustomerAccountById(customerAccountId.Value);
                purchaseRecord.Items = new List<PurchaseItem>();

                JArray array = JArray.Parse(purchaseItems);
                if (array != null && array.Count > 0)
                {
                    foreach (var item in array)
                    {
                        PurchaseItem purchaseItem = new PurchaseItem();

                        purchaseItem.PurchaseRecord = purchaseRecord;
                        purchaseItem.Product = this.ProductService.FindById(item["Product"].Value<int>("Id"));
                        purchaseItem.DonatedCount = item.Value<int>("DonatedCount");
                        purchaseItem.ChargedCount = item.Value<int>("ChargedCount");
                        purchaseRecord.Items.Add(purchaseItem);
                    }
                }

                this.ProductService.Purchase(purchaseRecord);

                return View("Purchase/Details", purchaseRecord);

            }

            return View("Purchase/Purchase");
        }

        /// <summary>
        /// 搜索购买记录
        /// </summary>
        /// <param name="start"></param>
        /// <param name="limit"></param>
        /// <param name="sort"></param>
        /// <param name="dir"></param>
        /// <returns></returns>
        public ActionResult SearchPurchaseRecord(int? start, int? limit, string sort, string dir)
        {
            if (this.Request.IsPost())
            {
                return base.ShowSearchResult("Purchase/SearchResult", "PurchaseRecord", start, limit, sort, dir);
            }

            return View("Purchase/Search");
        }

        /// <summary>
        /// 购买记录详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult PurchaseRecordDetails(int? id)
        {
            if (id == null)
            {
                throw new LogicalException();
            }

            PurchaseRecord purchaseRecord = this.ProductService.FindPurchaseRecordById(id.Value);
            if (purchaseRecord == null)
            {
                throw new LogicalException();
            }

            return View("Purchase/Details", purchaseRecord);
        }

        /// <summary>
        /// 打印产品购买记录
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult PrintPurchaseRecord(int? id)
        {
            if (id == null)
            {
                throw new LogicalException();
            }

            PurchaseRecord purchaseRecord = this.ProductService.FindPurchaseRecordById(id.Value);
            if (purchaseRecord == null)
            {
                throw new LogicalException();
            }

            return View("Purchase/Print", purchaseRecord);
        }

        /// <summary>
        /// 消耗产品
        /// </summary>
        /// <returns></returns>
        public ActionResult Consume(int? customerCardId, int? customerAccountId, string consumptionItems, string password)
        {
            ConsumptionRecord consumptionRecord = new ConsumptionRecord();

            if (this.Request.IsPost())
            {
                if (customerCardId != null)
                {
                    consumptionRecord.CustomerCard = this.CustomerService.FindCustomerCardById(customerCardId.Value);
                }
                if (customerAccountId == null)
                {
                    ModelState.AddModelError("CustomerAccountId", "请选择客户账户.");
                }
                else
                {
                    CustomerAccount customerAccount = this.CustomerService.FindCustomerAccountById(customerAccountId.Value);
                    if (customerAccount == null)
                    {
                        throw new LogicalException(string.Format("未找到 ID 为 {0} 的账户", customerAccountId));
                    }

                    consumptionRecord.CustomerAccount = customerAccount;
                }

                if (!string.IsNullOrEmpty(consumptionItems) && consumptionItems.StartsWith("[") && consumptionItems.EndsWith("]"))
                {
                    consumptionRecord.Items = new List<ConsumptionItem>();

                    JArray array = JArray.Parse(consumptionItems);
                    if (array != null && array.Count > 0)
                    {
                        foreach (var item in array)
                        {
                            ConsumptionItem consumptionItem = new ConsumptionItem();

                            consumptionItem.ConsumptionRecord = consumptionRecord;
                            consumptionItem.Product = this.ProductService.FindById(item["Product"].Value<int>("Id"));

                            CustomerAccountItem customerAccountItem = consumptionRecord.CustomerAccount.Items.FirstOrDefault(x => x.Product.Equals(consumptionItem.Product));
                            if (customerAccountItem == null)
                            {
                                ModelState.AddModelError("consumptionItems", "");
                            }
                            else
                            {
                                int consumeCount = item.Value<int>("ConsumeCount");
                                if (customerAccountItem.ChargedBalance >= consumeCount)
                                {
                                    consumptionItem.ChargedCount = consumeCount;
                                    consumptionItem.DonatedCount = 0;
                                }
                                else
                                {
                                    consumptionItem.ChargedCount = customerAccountItem.ChargedBalance;
                                    consumptionItem.DonatedCount = consumeCount - customerAccountItem.ChargedBalance;
                                }
                            }
                            consumptionRecord.Items.Add(consumptionItem);
                        }
                    }

                    if (string.IsNullOrEmpty(password))
                    {
                        ModelState.AddModelError("Password", "请输入密码.");
                    }
                    else
                    {
                        string hash = PasswordCryptor.Default.Encrypt(password);
                        if (consumptionRecord.CustomerCard.Password != hash)
                        {
                            ModelState.AddModelError("Password", "密码错误.");
                        }
                    }

                    if (ModelState.IsValid)
                    {
                        
                        this.ProductService.Consume(consumptionRecord);

                        return View("Consume/Details", consumptionRecord); 
                    }
                }
            }
            return View("Consume/Consume", consumptionRecord);
        }

        /// <summary>
        /// 消耗记录详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult ConsumptionRecordDetails(int? id)
        {
            if (id == null)
            {
                throw new LogicalException();
            }

            ConsumptionRecord purchaseRecord = this.ProductService.FindConsumptionRecordById(id.Value);
            if (purchaseRecord == null)
            {
                throw new LogicalException();
            }

            return View("Consume/Details", purchaseRecord);
        }

        /// <summary>
        /// 打印产品消耗记录
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult PrintConsumptionRecord(int? id)
        {
            if (id == null)
            {
                throw new LogicalException();
            }

            ConsumptionRecord consumptionRecord = this.ProductService.FindConsumptionRecordById(id.Value);
            if (consumptionRecord == null)
            {
                throw new LogicalException();
            }

            return View("Consume/Print", consumptionRecord);
        }

        /// <summary>
        /// 搜索产品消耗记录
        /// </summary>
        /// <param name="start"></param>
        /// <param name="limit"></param>
        /// <param name="sort"></param>
        /// <param name="dir"></param>
        /// <returns></returns>
        [CompressFilter]
        public ActionResult SearchConsumptionRecord(int? start, int? limit, string sort, string dir)
        {
            if (this.Request.IsPost())
            {
                return base.ShowSearchResult("Consume/SearchResult", "ConsumptionRecord", start, limit, sort, dir);
            }

            return View("Consume/Search");
        }

        /// <summary>
        /// 选择可购买产品
        /// </summary>
        /// <param name="start"></param>
        /// <param name="limit"></param>
        /// <param name="sort"></param>
        /// <param name="dir"></param>
        /// <returns></returns>
        public ActionResult SelectMarketablePorduct(int? start, int? limit, string sort, string dir)
        {
            if (start == null)
            {
                start = 0;
            }
            if (limit == null)
            {
                limit = 20;
            }

            ISearchContext searchContext = this.SearchService.CreateContext("Product");
            searchContext.SetFilter("Marketable", true);
            searchContext.SetSort("Name", false);

            return this.ShowSearchResult("", searchContext, start, limit, sort, dir);
        }

        /// <summary>
        /// 选择客户账户产品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult SelectCustomerAccountPorduct(int? id)
        {
            if (id == null)
            {
                throw new LogicalException();
            }

            CustomerAccount customerAccount = this.CustomerService.FindCustomerAccountById(id.Value);
            if (customerAccount == null)
            {
                throw new LogicalException();
            }

            return View(customerAccount);
        }
    }
}
